package com.mapforge.gui.map;

import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.mapforge.gui.tools.SelectedTiles;
import com.mapforge.listener.TileLayerSelectionEvent;
import com.mapforge.listener.TileLayerSelectionListener;
import com.mapforge.listener.TileMapCreationEvent;
import com.mapforge.listener.TileMapCreationListener;
import com.mapforge.listener.TileStampCreationEvent;
import com.mapforge.listener.TileStampCreationListener;
import com.mapforge.map.Tile;
import com.mapforge.map.TileLayer;
import com.mapforge.map.TileStamp;
import com.mapforge.map.Tileset;
import com.mapforge.map.tools.undo.TilePoint;
import com.mapforge.selection.ComparablePoint;
import com.mapforge.selection.TileSelection;

public class TileStampActionListener implements ActionListener,
		TileMapCreationListener, TileLayerSelectionListener {
	private Tileset tileset;
	/**
	 * {@link TileLayer} referenced in created {@link TileStamp tile stamps}.
	 */
	private TileLayer tileLayer;
	private List<TileStampCreationListener> tileStampCreationListeners;

	public TileStampActionListener() {
		this.tileStampCreationListeners = new ArrayList<TileStampCreationListener>();
	}

	public boolean addTileStampCreationListener(
			TileStampCreationListener listener) {
		return this.tileStampCreationListeners.add(listener);
	}

	public boolean removeTileStampCreationListener(
			TileStampCreationListener listener) {
		return this.tileStampCreationListeners.remove(listener);
	}

	public void clearTileStampCreationListeners() {
		this.tileStampCreationListeners.clear();
	}

	protected void fireTileStampCreationEvent(TileStampCreationEvent event) {
		for (int i = 0; i < this.tileStampCreationListeners.size(); i++) {
			this.tileStampCreationListeners.get(i).tileStampCreationPerformed(
					event);
		}
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		SelectedTiles selectedTiles = SelectedTiles.getHandle();
		Iterator<ComparablePoint> it = selectedTiles.iterator();
		if (it != null) {
			TileSelection selection = new TileSelection();
			Rectangle r = selectedTiles.getBoundingRectangle();
			ComparablePoint p;
			//int tilesetX, tilesetY, index;
			//int columns = tileset.getColumns();
			while (it.hasNext()) {
				p = it.next();
				Tile tile = this.tileLayer.getTileAt(p.x, p.y);
				//index = tile.getIndex();
				//tilesetY = index / columns;
				//tilesetX = index - tilesetY * columns;
				selection
						.addPoint(new TilePoint(tile, p.x - r.x + 1, p.y - r.y));
			}
			System.out
					.println("TileStampActionListener: Create tilesetamp, bounds = "
							+ selection.getBoundingRectangle());
			TileStamp tileStamp = new TileStamp(selection, tileset);
			TileStampCreationEvent event = new TileStampCreationEvent(e
					.getSource(), tileStamp);
			this.fireTileStampCreationEvent(event);
		}
	}

	@Override
	public void tileMapCreationPerformed(TileMapCreationEvent mapCreationEvent) {
		this.tileset = mapCreationEvent.getTileMapCreated().getTileset();
	}

	@Override
	public void tileLayerSelectionPerformed(TileLayerSelectionEvent event) {
		int num = event.getNumberLayersSelected();
		if (num == 1) {
			this.tileLayer = event.iterator().next();
		} else {
			this.tileLayer = null;
		}
	}

}
